package com.authine.cloudpivot.ext.utils;

import com.alibaba.cola.dto.RequestContext;
import com.alibaba.cola.exception.Exceptions;
import com.alibaba.fastjson.JSONObject;
import com.authine.hermes.app.operation.admin.dto.ErrorCode;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.controller.support.LocalDebugAppRouteBean;
import com.authine.mvp.controller.support.LocalDebugHeaderParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.core.env.Environment;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;

/**
 * @Author hxd
 * @Date 2021/10/14 19:58
 * @Description 云枢应用服务路径
 * http://ip/api/launcher/ordercenter/application/invoke?action=/ApplicationService/listBO
 * http://ip/api/launcher/${应用code}/application/invoke?action=${服务路径}
 **/
@Slf4j
public class AppUrl {

    public static final String listBo = "ApplicationService/listBO";


    public static String getUrl(String code, String serviceUrl) {
        String appUrl = getAppHost("app-launcher-".concat(code));
        if (StringUtils.isEmpty(appUrl)) {
            Exceptions.throwBizException(ErrorCode.APP_NOT_RUNNING);
        }
        return appUrl.concat("/application/invoke?action=").concat(serviceUrl);
    }


    /**
     * 获取应用host
     *
     * @param appCode
     * @return
     */
    public static String getAppHost(String appCode) {
        Environment environment = ApplicationContextUtils.getBean(Environment.class);
        String property = environment.getProperty("debugApplicationService");
        if (org.springframework.util.StringUtils.isEmpty(property) || "false".equals(property)) {
            LocalDebugAppRouteBean localDebugAppRouteBean = ApplicationContextUtils.getBean(LocalDebugAppRouteBean.class);
            return localDebugAppRouteBean.getBaseUrl(appCode, LocalDebugHeaderParam.builder()
                    .requestId(RequestContext.getRequestId()).loginName(RequestContext.getLoginName())
                    .requestId(RequestContext.getRequestId()).build());
        }
        DiscoveryClient discoveryClient = ApplicationContextUtils.getBean(DiscoveryClient.class);
        List<ServiceInstance> instances = discoveryClient.getInstances(appCode);
        if (CollectionUtils.isEmpty(instances)) {
            return null;
        }
        for (ServiceInstance instance : instances) {
            Map<String, String> metadata = instance.getMetadata();
            if (StringUtils.isEmpty(metadata.get("nodePort"))) {
                continue;
            }
            log.info("metadata:{}", JSONObject.toJSONString(metadata));
            String nodeIp = metadata.get("nodeIp");
            String nodePortStr = metadata.get("nodePort");
            return new DefaultServiceInstance(instance.getInstanceId(), instance.getServiceId(), nodeIp, Integer.parseInt(nodePortStr), false).getUri().toString();
        }
        return null;
    }


}
